# encoding: utf-8
import re
from . import db
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, BooleanField, TextAreaField
from wtforms.validators import required, email, equal_to, ValidationError
from .models import User, Blog, BlogAtUser, Topic, BlogRefTopic
from .constants import AT_USER_PATTERN, USERNAME_PATTERN, TOPIC_PATTERN

# 用户注册表单
class UserRegisterForm(FlaskForm):
    username = StringField("用户名：", validators=[required(message="请输入用户名！")])
    email = StringField("邮箱：", validators=[required(message="邮箱地址！"), email(message="请输入合法邮箱！")])
    password = PasswordField("密码：", validators=[required(message="请输入密码！")])
    confirmPassword = PasswordField("确认密码：", validators=[required(message="请输入确认密码！"), equal_to("password", message="两次密码不一致！")])
    submit = SubmitField("注册")

    # 用户注册
    def register(self, data):
        # 获取数据
        username = data.get("username")
        email = data.get("email")
        password = data.get("password")
        # 创建user实例
        user = User(username=username, email=email, password=password)
        # 添加到数据库
        db.session.add(user)
        db.session.commit()

    # 自定义验证用户名
    def validate_username(self, field):
        data = field.data
        # 验证用户名是否合法
        if not re.match(USERNAME_PATTERN, data):
            raise ValidationError("用户名不合法！")

        # 验证用户名是否超过20个字
        if len(data) > 20:
            raise ValidationError("不能超过20位！")

        # 验证用户名是否存在
        user = User.query.filter_by(is_valid=True, username=data).first()
        if user:
            raise ValidationError("此用户已存在！")
        return data

    # 自定义验证邮箱地址是否存在
    def validate_email(self, field):
        data = field.data
        user = User.query.filter_by(is_valid=True, email=data).first()
        if user:
            raise ValidationError("此邮箱已存在！")
        return data

# 用户登录表单
class UserLoginForm(FlaskForm):
    account = StringField("账户：", validators=[required(message="请填写账户！")])
    password = PasswordField("密码：", validators=[required(message="请填写密码！")])
    remember_me = BooleanField("记住我")
    submit = SubmitField("登录")

# 发布微博表单
class BlogForm(FlaskForm):
    content = TextAreaField("内容")
    submit = SubmitField("发布")

    def publish(self, user):
        data = self.data
        content = data.get("content")
        blog = Blog(content=content, user_id=user.id)
        db.session.add(blog)

        # 匹配@用户
        at_users = re.findall(AT_USER_PATTERN, content)
        for username in at_users:
            at_user = User.getUserByAccount(username)
            if at_user:
                blog_at_user = BlogAtUser(from_user_id=user.id, at_user_id=at_user.id, blog_id=blog.id)
                # 新增@用户记录
                db.session.add(blog_at_user)

        # 解析话题
        blog_topics = re.findall(TOPIC_PATTERN, content)
        for name in blog_topics:
            topic = Topic.getTopicByName(name)
            # 判断topic是否存在
            if not topic:
                topic = Topic(name=name)
                # 新增话题记录
                db.session.add(topic)
            blog_ref_topic = BlogRefTopic(blog_id=blog.id, topic_id=topic.id)
            # 新增博客关联话题记录
            db.session.add(blog_ref_topic)

        db.session.commit()